package cn.com.xy.sms.sdk.service.urlpreviewservice;

import java.util.Map;

import org.json.JSONArray;
import org.json.JSONObject;

import android.os.Process;
import cn.com.xy.sms.sdk.Iservice.XyCallBack;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.db.entity.UrlPreviewItem;
import cn.com.xy.sms.sdk.db.entity.UrlPreviewManager;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.net.NetUtil;
import cn.com.xy.sms.sdk.service.msgurlservice.MsgUrlService;
import cn.com.xy.sms.sdk.threadpool.SmartSmsThreadPoolManager;
import cn.com.xy.sms.sdk.util.CallBackState;
import cn.com.xy.sms.sdk.util.SdkCache;
import cn.com.xy.sms.sdk.util.StringUtils;
import cn.com.xy.sms.sdk.util.XyUtil;
import cn.com.xy.sms.util.ParseSmsMessage;
import cn.com.xy.sms.util.SdkCallBack;

public class UrlPreviewService {

    private static final String TAG = "UrlPreviewService";

    private static final long CYCLE_LONG = 10 * 60 * 1000;

    private static long LATEST_UPDATE_LONG = 0l;

    public static void getUrlPreviewData(final String msgId, final String phoneNum, final String url,
            final Map<String, String> extend, final SdkCallBack xyCallBack, boolean scrollFing) {
        int type = XyUtil.checkNetWork(Constant.getContext(), 2);
        try {
            if (StringUtils.isNull(msgId) || StringUtils.isNull(phoneNum) || StringUtils.isNull(url)) {
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NODATA, " param error",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_PREVIEW_VALUE_FLAG);
                return;
            }
            
            final String key = msgId + url;

            final SdkCache sdkCache = SdkCache.createSdkCache(phoneNum);

            JSONObject res = sdkCache.effectiveUrlPreviewData.get(key);
            if (res != null) {

                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_HASDATA, res, msgId,
                        ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_PREVIEW_VALUE_FLAG);
                return;
            }

            if (sdkCache.inQueueUrlPreviewData.contains(key)) {
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NODATA,
                        " inQueueUrlPreviewData", msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_PREVIEW_VALUE_FLAG);
                return;
            }

            if (!scrollFing) {
                sdkCache.inQueueUrlPreviewData.add(key);
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NEEDPARSE, " need parse",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_PREVIEW_VALUE_FLAG);

                SmartSmsThreadPoolManager.getMsgUrlPool().execute(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            SmartSmsThreadPoolManager.setThreadNameAndPriority(
                                    SmartSmsThreadPoolManager.TNAME_MSGURLPOOL, Process.THREAD_PRIORITY_BACKGROUND);
                            JSONObject object = readUrlPreviewResultFromDb(msgId, phoneNum, url);

                            if (object == null) {
                                requestUrlPreview(msgId, url, sdkCache, key, xyCallBack);
                            } else {
                                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_HASDATA,
                                        object, msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_PREVIEW_VALUE_FLAG);
                                sdkCache.inQueueUrlPreviewData.remove(key);
                                sdkCache.effectiveUrlPreviewData.put(key, object);
                                updateUrlPreview(url);
                            }

                        } catch (Throwable e) {
                        }
                    }
                }

                );

            } else {
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_SCOLLING, " is scrolling",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_PREVIEW_VALUE_FLAG);
            }
        } catch (Throwable e) {
        }
        // finally {
        // if (type != -1) {
        // updateUrlPreview();
        // }
        // }
    }

    public static synchronized void updateUrlPreview(final String url) {

        if (System.currentTimeMillis() < LATEST_UPDATE_LONG + CYCLE_LONG)
            return;

        executeRunnable(new Runnable() {
            @Override
            public void run() {
                try {
                    String urlNeedUpdate = UrlPreviewManager.queryCheckTimeExpireData(url);
                    urlPreviewNetBatch(urlNeedUpdate, true);
                } catch (Throwable e) {
                }

            }
        });

    }

    public static void urlPreviewNetBatch(String urlNeedUpdate, final boolean newThread) {
        try {
            if (StringUtils.isNull(urlNeedUpdate))
                return;
            final String dataString = getUrlPreviewReq(urlNeedUpdate);

            if (!StringUtils.isNull(dataString)) {
                NetUtil.requestNewTokenIfNeed(null);
                XyCallBack callBack = new XyCallBack() {

                    @Override
                    public void execute(Object... obj) {

                        if (obj == null || obj.length < 1) {
                            return;
                        }
                        int requestCode = (Integer) obj[0];

                        if (requestCode == CallBackState.REQUEST_SUCCESS) {

                            String response = obj[1].toString();
                            if (!StringUtils.isNull(response)) {
                                try {
                                    JSONObject resultObj = new JSONObject(response);
                                    JSONArray dataArr = resultObj.optJSONArray("data");
                                    JSONObject result = null;
                                    if (dataArr != null) {
                                        result = dataArr.optJSONObject(0);
                                    }
                                    if (result != null && result.has("url")) {
                                        String url = result.optString("url");
                                        persistData(url, result);
                                    }
                                } catch (Throwable e) {
                                }
                            }
                        }
                    }
                };
                NetUtil.executeServiceHttpRequest(NetUtil.URL_PREVIEW_SERVICE, dataString, null, callBack);
            }
        } catch (Throwable e) {
        } finally {
            synchronized (MsgUrlService.class) {
                LATEST_UPDATE_LONG = System.currentTimeMillis();
            }
        }
    }

    private static JSONObject readUrlPreviewResultFromDb(final String msgId, final String phoneNumber,
            final String url) {
        if (StringUtils.isNull(msgId) || StringUtils.isNull(url)) {
            return null;
        }
        UrlPreviewItem item = UrlPreviewManager.queryUrl(url);
        if (item != null) {
        }
        JSONObject jsonObject = null;
        if (item != null && !StringUtils.isNull(item.getData())) {
            try {
                jsonObject = new JSONObject(item.getData());
            } catch (Throwable e) {
            }
        } else {
            return null;
        }
        return jsonObject;

    }

    private static void requestUrlPreview(final String msgId, final String url, final SdkCache sdkCache,
            final String key, final SdkCallBack xyCallBack) {
        try {
            XyCallBack callBack = new XyCallBack() {
                @SuppressWarnings("unused")
                @Override
                public void execute(Object... obj) {

                    try {
                        if (obj != null && obj.length > 1) {

                            int requestCode = (Integer) obj[0];
                            if (requestCode != CallBackState.REQUEST_SUCCESS) {
                                return;
                            }

                            JSONObject resultObj = new JSONObject((String) obj[1]);
                            if (resultObj == null) {
                                return;
                            }
                            JSONArray dataArr = resultObj.optJSONArray("data");
                            if (dataArr != null && dataArr.length() > 0) {
                                JSONObject result = dataArr.optJSONObject(0);
                                if (result == null || result.length() == 0) {
                                    return;
                                }
                                persistData(url, result);
                                sdkCache.inQueueUrlPreviewData.remove(key);
                                sdkCache.effectiveUrlPreviewData.put(key, result);
                                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_HASDATA,
                                        result, msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_PREVIEW_VALUE_FLAG);
                            }
                        }
                    } catch (Throwable e) {
                    }
                }
            };

            JSONObject params = new JSONObject();
            String[] urls = url.split("_ARR_");

            JSONArray jsonArr = new JSONArray();
            if (urls != null) {
                for (String string : urls) {
                    jsonArr.put(string);
                }
            }

            params.put("urls", jsonArr);
            NetUtil.executeServiceHttpRequest(NetUtil.URL_PREVIEW_SERVICE, params.toString(), null, callBack);
        } catch (Throwable e) {
        }
    }

    private static void persistData(String url, JSONObject result) {
        UrlPreviewItem item = new UrlPreviewItem();
        item.setUrl(url);
        item.setData(result.toString());
        item.setDate(System.currentTimeMillis());
        UrlPreviewManager.insertOrUpdateUrl(url, item.getContentValues());
    }

    public static void executeRunnable(Runnable runnable) {
        SmartSmsThreadPoolManager.netWebPool.execute(runnable);
    }

    public static String getUrlPreviewReq(String urlNeedUpdate) {
        try {
            JSONArray jsonArray = new JSONArray();
            jsonArray.put(urlNeedUpdate);
            JSONObject json = new JSONObject();
            json.put("urls", jsonArray);
            return json.toString();
        } catch (Exception e) {
            LogManager.e(Constant.TAG, "ServerUtil getUrlPreviewReq(JSONArray phoneJsonArray): ", e);
        }
        return "";
    }

}
